package com.newly.center.sys.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.newly.api.sys.feign.TenantClient;
import com.newly.center.sys.service.role.api.IRoleService;
import com.newly.center.sys.service.tenant.api.ITenantService;
import com.newly.common.base.annotation.NewlyLog;
import com.newly.common.base.constants.CodeConstant;
import com.newly.common.base.constants.MenuConstant;
import com.newly.common.base.constants.ServerUriConstant;
import com.newly.common.base.entity.PageUtils;
import com.newly.common.base.entity.R;
import com.newly.common.base.entity.auth.ICurrentTenant;
import com.newly.common.base.entity.sys.auth.role.po.RolePo;
import com.newly.common.base.entity.sys.tenant.dto.*;
import com.newly.common.base.entity.sys.tenant.po.ExcelTenant;
import com.newly.common.base.entity.sys.tenant.po.TenantPo;
import com.newly.common.base.entity.sys.tenant.vo.TenantVo;
import com.newly.common.base.entity.sys.tenant.vo.UpdTenantVo;
import com.newly.common.base.exception.NewlyException;
import com.newly.common.core.utils.ExcelUtil;
import com.newly.common.core.utils.RequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author gjm guan
 * @date 2021/8/19 16:06
 * @desc 租户接口实现
 */
@RestController
@RequestMapping(ServerUriConstant.NEWLY_SYS_TENANT)
public class TenantApi implements TenantClient {

    @Autowired
    private ITenantService tenantService;

    @Autowired
    private RequestUtils requestUtils;

    @Autowired
    private IRoleService roleService;

    @Override
    public R create(TenantDto tenantDto) {
        boolean result = false;
        try {
            result = tenantService.save(tenantDto);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R change(TenantDto tenantDto) {
        return null;
    }

    @NewlyLog(ability = MenuConstant.Ability.DEL, title = "用户", isOpen = true)
    @Override
    public R deleteByIds(List<Long> tenantIds) {
        boolean result = false;
        try {
            result = tenantService.removeByIdsInAuth(tenantIds);
        } catch (Exception e) {
            e.printStackTrace();
            return R.ok(e.getMessage());
        }
        return R.ok(result);
    }

    @Override
    public R queryCurrentTenant() {
        TenantVo tenantVo = null;
        try {
            TenantPo tenantPo = tenantService.getCurrentTenant();
            if (!ObjectUtil.isEmpty(tenantPo)) {
                tenantVo = BeanUtil.copyProperties(tenantPo, TenantVo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(tenantVo);
    }

    @NewlyLog(ability = MenuConstant.Ability.QUE, title = "用户", isOpen = false)
    @Override
    public R listInAuth(Integer offset, Integer limit, Integer domainId, String fromTime,
                        String toTime, String keyword) {
        PageUtils pageUtils = null;
        try {
            pageUtils = tenantService.listInAuth(offset, limit, domainId, fromTime, toTime, keyword);
            if (!ObjectUtil.isEmpty(pageUtils) && !ObjectUtil.isEmpty(pageUtils.getList())) {
                pageUtils.setList(BeanUtil.copyToList(pageUtils.getList(), TenantVo.class));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }

        return R.ok(pageUtils);
    }

    @NewlyLog(ability = MenuConstant.Ability.ADD, title = "用户", isOpen = true)
    @Override
    public R create(CreateTenantDto tenantDto) {
        boolean result = false;
        try {
            result = tenantService.save(tenantDto);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(CodeConstant.SUCCESS, result, "创建租户成功！");
    }

    @NewlyLog(ability = MenuConstant.Ability.DEL, title = "用户", isOpen = true)
    @Override
    public R remove(List<Long> tenantIds) {
        boolean result = false;
        try {
            result = tenantService.logicDel(tenantIds);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
        return R.ok(CodeConstant.SUCCESS, result, "删除租户成功！");
    }

    @NewlyLog(ability = MenuConstant.Ability.EXP, title = "用户", isOpen = false)
    @Override
    public void export(String keyword, HttpServletResponse response) {
        ICurrentTenant currentTenant = requestUtils.getCurrentTenant();
        int totalCount = tenantService.listTenant(currentTenant, 1, 1, keyword).getTotalCount();
        if (totalCount < 1) {
            throw new NewlyException(CodeConstant.SUCCESS, "无用户数据");
        }
        List<TenantPo> list = tenantService.listTenant(currentTenant, 1, totalCount, keyword).getList();
        List<ExcelTenant> collect = list.stream().map(po -> {
            ExcelTenant excelTenant = new ExcelTenant();
            BeanUtil.copyProperties(po, excelTenant,
                    CopyOptions.create().ignoreCase().setIgnoreProperties("sex", "status", "createTime"));
            excelTenant/*.setSex(po.getSex() == 1 ? "男" : "女")*/
                    .setStatus(po.getStatus() == 1 ? "可用" : "禁用")
                    .setCreateTime(
                            DateUtil.format(po.getCreateTime(), "yyyy-MM-dd HH:mm:ss")
                    );
            return excelTenant;
        }).collect(Collectors.toList());

        ExcelUtil.export(response, "用户信息表", null, collect, ExcelTenant.class);
    }

    @NewlyLog(ability = MenuConstant.Ability.QUE, title = "用户", isOpen = false)
    @Override
    public R list(Integer offset, Integer limit, String keyword) {
        ICurrentTenant currentTenant = requestUtils.getCurrentTenant();
        PageUtils tenantPage = tenantService.listTenant(currentTenant, offset, limit, keyword);
        if (!ObjectUtil.isEmpty(tenantPage) && !ObjectUtil.isEmpty(tenantPage.getList())) {
            List<TenantPo> tenantPos = tenantPage.getList();
            List<TenantVo> tenantVos = tenantPos.stream().map(tenantPo -> {
                TenantVo tenantVo = BeanUtil.copyProperties(tenantPo, TenantVo.class);
                List<RolePo> rolePos = roleService.getByTenantId(tenantPo.getId());
                if (!ObjectUtil.isEmpty(rolePos)) {
                    tenantVo.setRoleId(rolePos.get(0).getId());
                }
                return tenantVo;
            }).collect(Collectors.toList());
            tenantPage.setList(tenantVos);
        }
        return R.ok(CodeConstant.SUCCESS, tenantPage, "查询租户列表成功！");
    }

    @Override
    public R currentTenant() {
        ICurrentTenant currentTenant = requestUtils.getCurrentTenant();
        TenantVo tenantVo = tenantService.parseCurrentTenant(currentTenant);
        return R.ok(CodeConstant.SUCCESS, tenantVo, "获取当前租户成功！");
    }

    @Override
    public R queryTenantById(Long tenantId) {
        UpdTenantVo updTenantVo = tenantService.queryTenantById(tenantId);
        return R.ok(CodeConstant.SUCCESS, updTenantVo, "查询租户成功");
    }

    @Override
    public R getUserNames() {
        List<String> userNames = this.tenantService.getUserNames();
        return R.ok(userNames);
    }

    @Override
    public R repeat(String userName) {
        if (StringUtils.isBlank(userName))
            return R.fail("参数userName不能不为空");
        return this.tenantService.repeat(userName) ? R.fail("用户名称已存在") : R.ok();
    }

    @Override
    public R repeatEmail(String email) {
        List<TenantPo> list = tenantService.repeatEmail(email);
        return list.size() > 0 ? R.fail("该邮箱已被使用") : R.ok();
    }

    @NewlyLog(ability = MenuConstant.Ability.UPD, title = "用户", isOpen = true)
    @Override
    public R updTenant(UpdTenantDto updTenantDto) {
        return tenantService.updTenant(updTenantDto) ? R.ok() : R.fail("修改失败");
    }

    @NewlyLog(ability = MenuConstant.Ability.UPD, title = "用户密码", isOpen = true)
    @Override
    public R updPassword(UpdPasswordDto updPasswordDto) {
        return tenantService.updPassword(updPasswordDto) ? R.ok() : R.fail("修改失败，密码错误");
    }

    @NewlyLog(ability = MenuConstant.Ability.UPD, title = "用户密码", isOpen = true)
    @Override
    public R updPasswordByEmail(UpdPasswordByEmailDto dto) {
        return tenantService.updPasswordByEmail(dto) ? R.ok() : R.fail("修改失败");
    }

    @Override
    public R isShowWindow() {
        ICurrentTenant currentTenant = requestUtils.getCurrentTenant();
        if (currentTenant.isDev()) {
            return R.ok(true);
        }
        if (currentTenant.getUserId().equals(1471053720660770817l)) {
            return R.ok(true);
        }
        return R.ok(false);
    }

}
